home *** CD-ROM | disk | FTP | other *** search
- /*
- ### driver for quality controlled integrator ###
-
- -----------------------------------------------------------------------------
- Note: - Integration is done in standard coods, that is, the coordinate system defining
- the original vector field.
- - Plotting is done in window coordinates, the coord system as defined in
- window_size panel
- -----------------------------------------------------------------------------
- - int_driver: 0 no sense of absolute time, integration from i=0 to i_max
- 1 knows absolute time, integration from int_start to int_end
- in int_nsteps;
- 2 knows absolute time, integration from int_start to int_end
- with variable steps but error tolerance less than int_eps
-
- - draw_all: 0 compute section by sampling at uniformly spaced
- discrete time intervals (int_period)
- -----------------------------------------------------------------------------
- - kount: counts the number of computed and displayed data (to be used for
- checking transients)
- BS case is not fully implemented since the number of points computed
- are usually small. The inclusion of intermediate points can be turned on
- by setting int_option=1 but these points are not accurate)
- -----------------------------------------------------------------------------
- THIS DRIVER DEALS ONLY WITH THE CASE int_driver=2
- SECTION COMPUTATION NOT IN A DIFFERENT WAY
- -----------------------------------------------------------------------------
- */
-
- #include <math.h>
- #define TINY 1.0e-30
-
- int kount;
-
- int
- ode_qc_forward()
- {
- int i,nstep,int_t_end;
- double int_t,int_next_step,int_actual_step,int_step;
- double *vfull,*y,*dydx,*dvector(),fabs();
- extern int nok,nbad,var_dim,func_dim,param_dim,full_dim;
- extern int model,polar_coord,stop,draw_all;
- extern int nok,nbad,int_driver,int_algorithm,int_max_nstep;
- extern double int_start,int_end,int_period,int_eps,int_guessed_step,int_min_step,*int_yscal;
- extern double *win_var_i,*win_var_f,*param;
- extern char string[];
- extern int (*f_p)();
-
-
- stop = 0;
- /* memory allocations */
- y = dvector(0,var_dim-1);
- dydx = dvector(0,var_dim-1);
- vfull= dvector(0,full_dim-1);
-
- kount = 0;
- nok = 0;
- nbad = 0;
- int_step = (int_end > int_start) ? fabs(int_guessed_step) : -fabs(int_guessed_step);
- int_t = int_start;
-
- /* intialize from starting window variables to standard variables */
- from_window_variables(y,win_var_i,polar_coord);
- to_full_variables(vfull,y,polar_coord);
- if(draw_all){
- (void) draw_record_orbit(vfull,0,0);
- }
-
- restart:
- if(!draw_all)
- int_t_end = int_t+int_period;
- else
- int_t_end = int_end;
-
- for(nstep = 1; nstep <= int_max_nstep; nstep++) {
- (int) f_p(dydx,0,y,param,int_t,var_dim);
- /* set the error scaling function */
- for(i=0;i<var_dim;i++)
- int_yscal[i] = fabs(y[i]) + fabs(dydx[i] * int_step) + TINY;
- /* do not draw and record intermediate orbits in the case of section */
- if(draw_all){
- to_full_variables(vfull,y,polar_coord);
- (void) draw_record_orbit(vfull,kount++,1);
- }
-
- /* set the final integration step of each
- integration segment to end at integer multiples
- of int_period after t_start */
- if((int_t + int_step - int_t_end) * (int_t + int_step - int_start) > 0.0) int_step = int_t_end -int_t;
-
- /* choose either runge-kutta or Bulirsch-Stoer quality controlled algorithm */
- if(int_algorithm == 0)
- (void) rkqc(y,dydx,var_dim,&int_t,int_step,int_eps,int_yscal,&int_actual_step,&int_next_step);
- else if(int_algorithm == 1)
- (void) bsstep(y,dydx,var_dim,&int_t,int_step,int_eps,int_yscal,&int_actual_step,&int_next_step);
-
- /* increment the number of bad or good steps */
- if(int_actual_step == int_step) ++nok; else ++nbad;
-
- /* Record the final data in each integration segment.
- While in the middle of integration segments
- restart the case of section. Otherwise exit. */
- if((int_t- int_t_end) * (int_t_end - int_start) >= 0.0) {
- to_full_variables(vfull,y,polar_coord);
- (void) draw_record_orbit(vfull,kount++,1);
- /* in case of section, continue until t < t(end) */
- if(!draw_all && int_t < int_end)
- goto restart;
- else
- goto done;
- }
-
- /* if integration step is smaller than int_min_step exit */
- if( fabs(int_next_step) <= int_min_step) {
- system_mess_proc(1,"ode_qc_forward: Step size too small.Stop!");
- goto done;
- }
- if(stop){
- goto done;
- }
- int_step = int_next_step;
- }
- system_mess_proc(1,"ode_qc_forward: Too many steps. Stop!");
-
- done:
- /* reset the final value of window variables */
- to_window_variables(win_var_f,y,polar_coord);
- if(int_algorithm==0)
- printf("Runge-Kutta QC Integ: nok=%d,nbad=%d\n",nok,nbad);
- else if(int_algorithm == 1)
- printf("Bulirsch-Stoer QC Integ: nok=%d,nbad=%d\n",nok,nbad);
- (void) free_dvector(dydx,0,var_dim-1);
- (void) free_dvector(y,0,var_dim-1);
- (void) free_dvector(vfull,0,full_dim-1);
- /* should be changed to return "time" instead ; return(int_t) */
- return(kount);
- }
-
-